//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<tick_scheduler.h>
///	@path	~/src/engine/xcore
///	@date	2008/03/23
///	@desc	.

#pragma once

#include "xeres.h"

#include "lib/utilities/dep_stages.h"

#include "engine/xcore/frame_control.h"

namespace xeres {

	/*! 
		\class	TickScheduler
		\brief	Tick loop scheduler.

		\details
			
		\par Game loop stages:

							>> synchronized
				$				-	immediate execute stage, some pre-process goes to here.(before render).
							>> asynchronized
				input			-	for input message updates.
				logic			-	game logic updates, including AI.
				physic			-	physics calculation.
				scene			-	for scene manager update, and scene updates, usually self-activate ILive objects.
				debug			-	debugging update.
				ui				-	for user's interface update.
				final			-	run after all done.
							>> synchronized
				sync			-	specific stages run after synchronization (if parallelized tick/render)
		<BR>
		\par System defined stage:
			
				$/input			-	basic input handling, will translate user input into events.
				$/message		-	some basic windows message, will translate into events.
				$/device		-	for device update, resize or reset.
				input/.			-	handle input subscribers.
				input/event		-	event post system.
				input/timer		-	timer calls.
				logic/.			-	preparation for logic update.
				logic/entity	-	entity update.
				logic/scenario	-	current scenario update.
				scene/.			-	scene manager updates.
				scene/world		-	world update, calculate ILive & IEntity.
				scene/present	-	present update, for all presentations.
				debug/.			-	basic debug update.
				ui/.			-	basic ui update.
	*/
	class TickScheduler : public FrameControl
	{
	protected:

		/// \name Constructor & Destructor
		//@{

		/// \ctor
		TickScheduler( void );

		/// \dtor
		~TickScheduler( void );

		//@}

		/// \name Internal Manipulation
		//@{

		/*!
			\brief		Resolve loop rules.
		*/
		void ResolveLoopStage( void );

		/*!
			\brief		Update game context before render.
		*/
		void TickFrame( void );

		/*!
			\brief		Root call for update. Resolved as '$' `s children.
		*/
		void UpdateRootCall( void );

		/*!
			\brief		Call after update synchronized. Resolved as 'sync' `s children.
		*/
		void UpdateSyncCall( void );

		//@}

	public:

		///	\name	Loop Controls
		//@{

		/*!
			\brief		Insert game loop stage.
						Notice if stage depends on no stage,
						system will assign root stage '.' for it.
		*/
		bool InsertStage( const WString& stage , const WString& dep , function<void(const Frame&)> exec_call );

		/*!
			\brief		Delete specific loop stage.
		*/
		bool DeleteStage( const WString& stage );

		/*!
			\brief		Replace exist stage.
		*/
		bool ReplaceStage( const WString& stage , function<void(const Frame&)> exec_call );

		/*! 
			\brief		Reset all stages.
		*/
		void ResetStages( void );

		//@}

	private:

		//@ data

		// tags
		bool				m_reorderLoop; // tag to active loop re-order
		bool				m_spare[3];

		// game loop stages
		dep_stages< function<void(const Frame&)> >		m_loopStages;

		std::vector< function<void(const Frame&)> >		m_loopRootCalls;
		std::vector< function<void(const Frame&)> >		m_loopCalls;
		std::vector< function<void(const Frame&)> >		m_loopSyncCalls;

	};

} // namespace xeres
